﻿using Rhino;
using Rhino.Display;
using Rhino.DocObjects;
using Rhino.Geometry;
using System.Collections.Generic;
using System.Drawing;

namespace AiMoRhino.Preview
{
    class Previewer : DisplayConduit
    {
        readonly MouseClick mouseClick;
        public Previewer()
        {
            mouseClick = new MouseClick(this);
        }
        BoundingBox ClippingBox = BoundingBox.Empty;
        public void Clear()
        {
            LoopOn = false;
            previewObjects.Clear();
            ClippingBox = BoundingBox.Empty;
        }
        public void ClosePreview()
        {
            Clear();
            Enabled = false;
            mouseClick.Enabled = false;
            RhinoDoc.ActiveDoc.Views.Redraw();
        }

        public void EnableDraw()
        {
            Enabled = true;
            mouseClick.Enabled = true;
        }

        public static Color DefaultColor = Color.FromArgb(150, 2, 45, 80);

        readonly List<PreviewObject> previewObjects = new List<PreviewObject>();

        public bool IsEmpty => previewObjects.Count == 0 && (!LoopOn);
        public bool LoopOn { get; set; } = false;
        protected override void PostDrawObjects(DrawEventArgs e)
        {
            foreach (PreviewObject previewObject in previewObjects)
            {
                try
                {
                    if (previewObject != null && previewObject.Enable)
                    {
                        previewObject.Draw(e.Display);
                    }
                }
                catch
                {
                }
            }
        }

        const float buttonWidth = 140;
        const float buttonHeight = 35;
        public RectangleF PreviewRec { get; private set; } = RectangleF.Empty;

        static readonly Color fillColor = Color.FromArgb(0, 35, 67);
        static readonly Color edgeColor = Color.FromArgb(5, 60, 99);
        protected override void DrawOverlay(DrawEventArgs e)
        {
            if ((!IsEmpty) && e.Viewport.Id == RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewportID)
            {
                PreviewRec = new RectangleF(e.Viewport.Bounds.Width - (buttonWidth + buttonHeight * 0.2f), (buttonHeight * 0.2f), buttonWidth, buttonHeight);
                PointF PreviewRecCenter = new PointF(PreviewRec.X + PreviewRec.Width / 2, PreviewRec.Y + PreviewRec.Height / 2);
                e.Display.Draw2dText("Preview Off", Color.White, new Point2d(PreviewRecCenter.X, PreviewRecCenter.Y), true, 16, "Arial Black");
                e.Display.DrawRoundedRectangle(PreviewRecCenter, PreviewRec.Width, PreviewRec.Height, 5, edgeColor, 4, fillColor);
            }
        }
        protected override void CalculateBoundingBox(CalculateBoundingBoxEventArgs e)
        {
            e.IncludeBoundingBox(ClippingBox);
        }

        public void Preview(Vector3d vector3d, Point3d from, Color color)
        {
            if (from.IsValid && vector3d.IsValid && (!vector3d.IsZero))
            {
                PreviewVector previewVector = new PreviewVector(vector3d, from, color);
                previewObjects.Add(previewVector);
                ClippingBox.Union(previewVector.ClippingBox);
            }
        }
        public void Preview(object geo, Color color)
        {
            switch (geo)
            {
                case Point3d pt:
                    if (pt.IsValid)
                    {
                        previewObjects.Add(new PreviewPoint(pt, color));
                    }
                    break;
                case Point3f ptf:
                    if (ptf.IsValid)
                    {
                        previewObjects.Add(new PreviewPoint(new Point3d(ptf), color));
                    }
                    break;
                case PointCloud cloud:
                    if (cloud.IsValid)
                    {
                        previewObjects.Add(new PreviewPointCloud(cloud, color));
                    }
                    break;
                case Line line:
                    if (line.IsValid)
                        previewObjects.Add(new PreviewStructGeos(line, color));
                    break;
                case Box box:
                    if (box.IsValid)
                        previewObjects.Add(new PreviewBox(box, color));
                    break;
                case BoundingBox bbox:
                    if (bbox.IsValid)
                        previewObjects.Add(new PreviewBox(new Box(bbox), color));
                    break;
                case Circle circle:
                    if (circle.IsValid)
                        previewObjects.Add(new PreviewCircle(circle, color));
                    break;
                case Arc arc:
                    if (arc.IsValid)
                        previewObjects.Add(new PreviewArc(arc, color));
                    break;
                case Ellipse ellipse:
                    if (ellipse.IsValid)
                        previewObjects.Add(new PreviewCurve(ellipse.ToNurbsCurve(), color));
                    break;
                case Cone cone:
                    if (cone.IsValid)
                        previewObjects.Add(new PreviewCone(cone, color));
                    break;
                case Rectangle3d rectangle:
                    if (rectangle.IsValid)
                        previewObjects.Add(new DrawPolyline(rectangle.ToPolyline(), color));
                    break;
                case Polyline polyline:
                    if (polyline.IsValid && polyline.Count > 1)
                        previewObjects.Add(new DrawPolyline(polyline, color));
                    break;
                case Cylinder cylinder:
                    if (cylinder.IsValid)
                        previewObjects.Add(new DrawCylinder(cylinder, color));
                    break;
                case Plane plane:
                    if (plane.IsValid)
                        previewObjects.Add(new PreviewPlane(plane, color));
                    break;
                case Sphere sphere:
                    if (sphere.IsValid)
                        previewObjects.Add(new DrawSphere(sphere, color));
                    break;
                case AnnotationBase annotationBase:
                    previewObjects.Add(new PreviewAnnotationBase(annotationBase, color));
                    break;
                case Hatch hatch:
                    previewObjects.Add(new PreviewHatch(hatch, color));
                    break;
                case TextDot textDot:
                    previewObjects.Add(new PreviewTextDot(textDot, color));
                    break;

                case Curve crv:
                    previewObjects.Add(new PreviewCurve(crv, color));
                    break;
                case Text3d text3D:
                    previewObjects.Add(new PreviewText3d(text3D, color));
                    break;
                case GeometryBase geometry:
                    previewObjects.Add(new PreviewGeometryBase(geometry, color));
                    break;
                case RhinoObject rhinoObject:
                    previewObjects.Add(new PreviewRhinoObject(rhinoObject, color));
                    break;
            }
            if (previewObjects.Count > 0)
                ClippingBox.Union(previewObjects[previewObjects.Count - 1].ClippingBox);
        }


    }
}
